package com.tongtong.utils;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.tongtong.common.WebConstants;
import com.ttio.netty.utils.ChannelUtils;
import com.ttio.netty.utils.MessageUtils;
import io.netty.channel.Channel;
import lombok.Data;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Title: ChannelUtilsV2
 * @Author zl
 * @Package com.tongtong.utils
 * @Date 2025/6/27 16:56
 * @description: 升级优化
 * 提供与Netty通道相关的实用方法，包括发送消息、房间用户管理等功能。
 */
public class ChannelUtilsV2 extends MessageUtils {

    /**
     * 向除指定通道外的所有其他通道发送消息。
     * @param key 需要排除的通道标识符。
     * @param maps 要发送的消息对象。
     */
    public static void sendOtherChannel(String key, Map<String,Object> maps) {
        Set<String> keys = ChannelUtils.getChannelGroup().stream().filter(item -> !ChannelUtils.getChannelKey(item).equals(key)).map(item -> ChannelUtils.getChannelKey(item)).collect(Collectors.toSet());
        sendMoreMessage(keys, maps);
    }

    /**
     * 向除指定通道外的所有其他通道发送消息（特定于房间操作）。
     * @param key 需要排除的通道标识符。
     * @param maps 要发送的消息对象。
     */
    public static void sendRoomOtherChannel(String key, Map<String,Object> maps) {
        //获取用户所在房间id
        if(Objects.nonNull(RedisUtils.get(WebConstants.redisUserkey + key))){
            String redisKey = WebConstants.redisRoomUserKey + RedisUtils.get(WebConstants.redisUserkey + key);
            Set<String> userIds = RedisUtils.setMembers(redisKey).stream().map(item -> item.split("=")[0]).filter(item -> !item.equals(key)).collect(Collectors.toSet());
            sendMoreMessage(userIds, maps);
        }
    }

    /**
     * 用户离开或下线时，从房间中移除其信息，并通知其他用户和更新房间用户计数。
     * @param userInfo 离开房间的用户的信息。
     */
    public static void leaveRoomUser(UserInfo userInfo) {

        String userId = userInfo.getUserId();
        String roomId = RedisUtils.get(WebConstants.redisUserkey + userId);
        String roomIdKey = WebConstants.redisRoomUserKey + roomId;
        String value = userInfo.getUserId()+"="+userInfo.getUserName();
        //删除房间用户信息
        RedisUtils.sRemove(roomIdKey, value);
        //删除用户房间信息
        RedisUtils.delete(WebConstants.redisUserkey + userId);
        //获取房间用户id 并 推送消息
        Map<String, Object> result = queryRoomUser(roomId,"leave-room");
        result.put("userCount",RedisUtils.sSize(roomIdKey));
        result.put("user",userInfo);
        Set<String> strings = RedisUtils.setMembers(roomIdKey);
        Set<String> userIds = strings.stream().map(item -> item.split("=")[0]).collect(Collectors.toSet());
        Map<String, Object> maps = new HashMap<>();
        maps.put("data", JSONUtil.toJsonStr(result));
        sendMoreMessage(userIds, maps);
        //推送给所有用户房间总用户数
        result.remove("user");
        result.put("type","room-count");
        maps.put("data", JSONUtil.toJsonStr(result));
        sendAllMessage(maps);
    }

    /**
     * 用户加入指定房间，并通知房间内其他用户及更新房间用户计数。
     * @param userId 加入房间的用户的ID。
     * @param roomId 用户加入的房间的ID。
     */
    public static void joinRoomUser(String userId,String roomId){
        String roomIdKey = WebConstants.redisRoomUserKey + roomId;
        UserInfo userInfo = queryUserInfoByUserId(userId);
        String value = userInfo.getUserId()+"="+userInfo.getUserName();
        //存储房间用户列表
        RedisUtils.sAdd(roomIdKey, value);
         //存储用户房间信息
        RedisUtils.set(WebConstants.redisUserkey + userId, roomId);
        Map<String, Object> result = queryRoomUser(roomId,"join-room");
        result.put("userCount",RedisUtils.sSize(roomIdKey));
        result.put("user",userInfo);
        //获取房间用户id 并 推送消息
        Set<String> strings = RedisUtils.setMembers(roomIdKey);
        Set<String> userIds = strings.stream().map(item -> item.split("=")[0]).collect(Collectors.toSet());
        Map<String, Object> maps = new HashMap<>();
        maps.put("data", JSONUtil.toJsonStr(result));
        sendMoreMessage(userIds, maps);
        //推送给所有用户房间总用户数
        result.remove("user");
        result.put("type","room-count");
        maps.put("data", JSONUtil.toJsonStr(result));
        sendAllMessage(maps);
    }

    /**
     * 根据用户ID查询用户详细信息。
     * @param userId 要查询的用户的ID。
     * @return 包含用户ID和用户名的UserInfo对象。
     */
    public static UserInfo queryUserInfoByUserId(String userId){
        JSONObject channelKey = JSONUtil.parseObj(ChannelUtils.getChannelExtend(userId));
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(channelKey.getStr("userId"));
        userInfo.setUserName(channelKey.getStr("userName"));
        return userInfo;
    }

    /**
     * 根据提供的Netty通道查询关联的用户详细信息。
     * @param channel 要查询的Netty通道。
     * @return 包含用户ID和用户名的UserInfo对象。
     */
    public static UserInfo queryUserInfoByChannel(Channel channel){
        JSONObject channelKey = JSONUtil.parseObj(ChannelUtils.getChannelExtend(channel));
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(channelKey.getStr("userId"));
        userInfo.setUserName(channelKey.getStr("userName"));
        return userInfo;
    }


    /**
     * 构建包含房间ID和操作类型的响应数据。
     * @param roomId 操作涉及的房间ID。
     * @param type 表示操作类型（如加入房间、离开房间）。
     * @return 包含房间ID和操作类型的Map对象。
     */
    public static Map<String,Object> queryRoomUser(String roomId,String type){
        Map<String,Object> result = new HashMap<>();
        result.put("roomId",roomId);
        result.put("type",type);
        return result;
    }

    @Data
    public static class UserInfo{
        private String userId;
        private String userName;
    }


}

